﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;

namespace BoYuanCore.Framework.MemoryCache
{
    //参考 https://www.cnblogs.com/fanfan-90/p/12151924.html

    /// <summary>
    /// RedisCache
    /// </summary>
    public class RedisCaching : ICachingProvider, IDisposable
    {
        /*
        安装 Microsoft.Extensions.Caching.Redis包，

直接使用：（RedisCache实现了接口IDistributedCache）
         */


        private readonly IDistributedCache _myCache;// = new RedisCache(new RedisCacheOptions());
        private readonly IConfiguration _configuration;
        private readonly int _cacheTime;

        public RedisCaching(IConfiguration configuration, IDistributedCache cache)
        {
            this._configuration = configuration;
            _cacheTime = this._configuration.GetValue<int>("CACHE_TIME");
            _myCache = cache;
        }

        public void Dispose()
        {
            //this._myCache?.Dispose();
        }

        public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0)
        {
            T cacheObject = default(T);
            byte[] cacheObj = this._myCache.Get(cacheItemName);

            if (cacheObj != null)
            {
                var stringObject = Encoding.UTF8.GetString(cacheObj);//通过UTF-8编码，将字节数组反序列化为Json字符串
                cacheObject = JsonConvert.DeserializeObject<T>(stringObject, new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.All
                });
            }
            else
            {
                cacheObject = objectSettingFunction();
                var stringObject = JsonConvert.SerializeObject(cacheObject, new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    TypeNameHandling = TypeNameHandling.All
                });

                var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码，序列化为字节数组

                this._myCache.Set(cacheItemName, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes) });
            }
            this._myCache.Refresh(cacheItemName);
            return cacheObject;
        }

        public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120)
        {
            var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                TypeNameHandling = TypeNameHandling.All
            });

            var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码，序列化为字节数组
            this._myCache.Set(key, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes) });
        }


        /// <summary>
        /// 从Redis中刷新键值
        /// </summary>
        /// <param name="key">缓存键</param>
        public void Refresh(string key)
        {
            this._myCache.Refresh(key);
        }


        public object GetValueFromCache(string key)
        {
            return this._myCache.Get(key);
        }

        public void Remove(string key)
        {
            this._myCache.Remove(key);
        }

        public void RemoveAll()
        {
            throw new NotImplementedException();
        }


    }
}
